﻿/*
 *  Copyright 2012 Cloudbase Solutions Srl
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the Microsoft Public License (Ms-PL).  
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using Microsoft.Web.Management.Client.Win32;
using Microsoft.Web.Management.Client;
using System.Collections;
using System.Net;
using System.Diagnostics;
using System.IO;
using System.Threading;
using Cloudbase.Iis.HostsFileManager.Common;
using Cloudbase.Iis.HostsFileManager.Model;
using System.ComponentModel;

namespace Cloudbase.Iis.HostsFileManager.Client
{
    internal class HostsFileModuleListPage : ModuleListPage
    {
        class HostsFileTaskList : TaskList
        {
            private HostsFileModuleListPage owner;

            public HostsFileTaskList(HostsFileModuleListPage owner)
            {
                this.owner = owner;
            }

            public override ICollection GetTaskItems()
            {
                List<TaskItem> l = new List<TaskItem>();

                var i = new MethodTaskItem("AddHostEntry", StringResource.AddHostEntry, "New");
                l.Add(i);

                if (owner.ListView.SelectedItems.Count != 0)
                {
                    i = new MethodTaskItem("EditHostEntry", StringResource.EditHostEntry, "New");
                    l.Add(i);

                    i = new MethodTaskItem("RemoveHostEntry", StringResource.RemoveHostEntry, "New");
                    l.Add(i);
                }

                i = new MethodTaskItem("OpenHostsFileExternally", StringResource.OpenHostsFileExternally, "New");
                i.Enabled = owner.Connection.IsLocalConnection;
                l.Add(i);

                i = new MethodTaskItem("RefreshHostEntries", StringResource.RefreshHostEntries, "New");
                l.Add(i);

                return l;
            }

            public void AddHostEntry()
            {
                owner.AddHostEntry();
            }

            public void EditHostEntry()
            {
                owner.EditHostEntry();
            }

            public void RemoveHostEntry()
            {
                owner.RemoveHostEntry();
            }

            public void OpenHostsFileExternally()
            {
                owner.OpenHostsFileExternally();
            }

            public void RefreshHostEntries()
            {
                owner.RefreshHostEntries();
            }
        }

        private ColumnHeader ipColumnHeader;
        private ColumnHeader hostColumnHeader;
        private ColumnHeader commentColumnHeader;
        private HostsFileTaskList tl;
        private FileSystemWatcher fsw;

        private IHostsFileModuleService svc;

        public HostsFileModuleListPage()
        {
            tl = new HostsFileTaskList(this);
            ListView.SelectedIndexChanged += new EventHandler(ListView_SelectedIndexChanged);
            ListView.MouseDoubleClick += new MouseEventHandler(ListView_MouseDoubleClick);
        }

        void ListView_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            EditHostEntry();
        }

        private void ListView_SelectedIndexChanged(object sender, EventArgs e)
        {
            Update();
        }
 
        private void AddHostEntry()
        {
            AddOrEditHostEntry(true, null, null, null);
        }

        private void AddOrEditHostEntry(bool isAdd, string host, IPAddress ipAddress, string comment)
        {
            HostsFileEntryForm form = new HostsFileEntryForm(ServiceProvider, svc, isAdd, host, ipAddress, comment);
            if (ShowDialog(form) == DialogResult.OK)
            {
                try
                {
                    if(isAdd)
                        svc.AddHost(form.Host, form.IPAddress, form.Comment);
                    else
                        svc.UpdateHost(host, form.Host, form.IPAddress, form.Comment);

                    LoadData();
                }
                catch (Exception ex)
                {
                    ShowError(ex, true);
                }
            }
        }

        private void OpenHostsFileExternally()
        {
            Process.Start("Notepad.exe", svc.GetHostsFilePath());
        }

        private void EditHostEntry()
        {
            var si = ListView.SelectedItems[0];

            string host = si.Text;
            IPAddress ipAddress = IPAddress.Parse(si.SubItems[1].Text);
            string comment = si.SubItems[2].Text;

            AddOrEditHostEntry(false, host, ipAddress, comment);
        }

        private void RemoveHostEntry()
        {
            var si = ListView.SelectedItems[0];
            string host = si.Text;

            if (ShowMessage(string.Format(StringResource.RemoveHostEntryMessage, host), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                svc.RemoveHost(host);
                LoadData();
            }
        }

        private void RefreshHostEntries()
        {
            LoadData();
        }

        protected override TaskListCollection Tasks
        {
            get
            {
                TaskListCollection tlc = base.Tasks;
                tlc.Add(tl);
                return tlc;
            }
        }

        protected override void OnActivated(bool initialActivation)
        {
            base.OnActivated(initialActivation);

            //StartWatchingHostsFileChanges();

            if (initialActivation)
            {
                svc = (IHostsFileModuleService)CreateProxy(typeof(HostsFileModuleServiceProxy));
                LoadData();
            }
        }

        /*
        private void StartWatchingHostsFileChanges()
        {
            if (fsw == null)
            {
                var path = svc.GetHostsFilePath();
                fsw = new FileSystemWatcher(Path.GetDirectoryName(path), Path.GetFileName(path));
                fsw.NotifyFilter = NotifyFilters.LastWrite;
                fsw.Changed += new FileSystemEventHandler(fsw_Changed);
                fsw.EnableRaisingEvents = true;
            }
        }

        private void StopWatchingHostsFileChanges()
        {
            if (fsw != null)
            {
                fsw.Dispose();
                fsw = null;
            }
        }
         */ 

        protected override void OnDeactivating(System.ComponentModel.CancelEventArgs e)
        {
            base.OnDeactivating(e);
            //StopWatchingHostsFileChanges();
        }

        void fsw_Changed(object sender, FileSystemEventArgs e)
        {
            // Be sure to invoke it in the UI thread
            this.BeginInvoke(new MethodInvoker(delegate() { LoadData(); }));
        }

        private void LoadData()
        {
            StartAsyncTask(StringResource.LoadHostFileEntriesProgress,
                           new DoWorkEventHandler((sender, e) => { e.Result = svc.GetAllEntries(); }),
                           new RunWorkerCompletedEventHandler((sender, e) => {
                               ListView.BeginUpdate();
                               try
                               {
                                   ListView.Items.Clear();
                                   foreach (var entry in (IList<HostFileEntry>)e.Result)
                                   {
                                       HostFileEntry h = (HostFileEntry)entry;

                                       ListViewItem item = new ListViewItem();
                                       item.Text = h.Host;
                                       item.SubItems.Add(h.IPAddress.ToString());
                                       item.SubItems.Add(h.Comment);

                                       ListView.Items.Add(item);
                                   }
                               }
                               finally
                               {
                                   ListView.EndUpdate();
                               }                           
                           }));
        }

        protected override void InitializeListPage()
        {
            hostColumnHeader = new ColumnHeader();
            hostColumnHeader.Text = StringResource.HostColumnHeader;
            hostColumnHeader.Width = 200;

            ipColumnHeader = new ColumnHeader();
            ipColumnHeader.Text = StringResource.IPAddressColumnHeader;
            ipColumnHeader.Width = 200;

            commentColumnHeader = new ColumnHeader();
            commentColumnHeader.Text = StringResource.CommentColumnHeader;
            commentColumnHeader.Width = 200;

            ListView.Columns.Add(hostColumnHeader);
            ListView.Columns.Add(ipColumnHeader);
            ListView.Columns.Add(commentColumnHeader);
        }
    }
}
